import java.awt.Dialog;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JMenu;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import xml.utils.XmlDocument;
import xml.utils.XmlException;
import xml.utils.XmlNode;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


public class ServerWindow{

	public JFrame frmServermanager;
	XmlDocument xmlConfiguration;
	XmlNode xmlRoot;
	String strLog;
	File fileLog;
	URL urlPath;
	String strPath;
	String strFileName;
	DateFormat dateFormat;
	Date date;
	String strHost;
	String strRegistry;
	AccessDBInterface accServer;
	List<XmlNode> lstHost;
	List<XmlNode> lstRegistry;
	private JTextArea txtrServersLog;
	private JMenuBar menuBar;
	private JMenuItem mntmLoadConfiguration;
	private JMenu mnMain;
	private JMenuItem mntmStop;
	private JMenuItem mntmExit;
	private JMenuItem mntmStart;
	private JMenuItem mntmTwoPhaseCommit;
	private JMenu mnSynchronize;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ServerWindow window = new ServerWindow();
					window.frmServermanager.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public ServerWindow() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	@SuppressWarnings("deprecation")
	private void initialize() {
		//Variables' initialization
		urlPath = ServerWindow.class.getResource("ServerWindow.class");
		strPath = urlPath.toString();
		strPath = strPath.substring(6, strPath.lastIndexOf("/") + 1);
		strLog = new String();
		dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		date = new Date();
		strFileName = new String("logServer" + date.getDate() + "." + date.getMonth() + "." + (date.getYear() + 1900) + "_" + date.getHours() + "." + date.getMinutes() + "." + date.getSeconds() + ".txt");
		fileLog = new File(strPath + strFileName);

		//Control's initialization
		frmServermanager = new JFrame();
		frmServermanager.setTitle("ServerManager");
		frmServermanager.setBounds(100, 100, 450, 300);
		frmServermanager.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frmServermanager.getContentPane().setLayout(null);

		txtrServersLog = new JTextArea();
		txtrServersLog.setBounds(0, 0, 434, 241);
		frmServermanager.getContentPane().add(txtrServersLog);
		
		menuBar = new JMenuBar();
		frmServermanager.setJMenuBar(menuBar);
		
		mnMain = new JMenu("Main");
		menuBar.add(mnMain);
		
		mntmLoadConfiguration = new JMenuItem("Load configuration");
		mnMain.add(mntmLoadConfiguration);
		
		mntmStart = new JMenuItem("Start");
		mnMain.add(mntmStart);
		mntmStart.setEnabled(false);
		
		mntmStop = new JMenuItem("Stop");
		mnMain.add(mntmStop);
		mntmStop.setEnabled(false);
		
		mntmExit = new JMenuItem("Exit");
		mnMain.add(mntmExit);
		
		mnSynchronize = new JMenu("Synchronize");
		menuBar.add(mnSynchronize);
		mnSynchronize.setEnabled(false);
		
		mntmTwoPhaseCommit = new JMenuItem("Two Phase Commit");
		mnSynchronize.add(mntmTwoPhaseCommit);
		mntmTwoPhaseCommit.setEnabled(false);
		
		//Event handling
		
		mntmLoadConfiguration.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				try {					
					xmlConfiguration = new XmlDocument();
					xmlRoot = xmlConfiguration.parse(strPath + "otherservers_1.xml");
					
					writeFileLog("Loading Configuration...\n");
					txtrServersLog.setText(readFileLog(fileLog));					
					
					int numberofservers = Integer.parseInt(xmlRoot.getTagValue("numberofotherservers"));
					writeFileLog("Number of servers: " + numberofservers + "\n");
					txtrServersLog.setToolTipText(readFileLog(fileLog));
					
					lstHost = xmlRoot.getNodesByTagName("host");
					lstRegistry = xmlRoot.getNodesByTagName("registry");
					
					for (int i = 1; i <= numberofservers; i++) {
						writeFileLog("Server IP: " + lstHost.get(i).getNodeValue() + ", with registry: " + lstRegistry.get(i).getNodeValue() + "\n");
					}
					txtrServersLog.setText(readFileLog(fileLog));

					writeFileLog("OK!!!\n");
					txtrServersLog.setText(readFileLog(fileLog));
					
					mntmStart.setEnabled(true);
					mntmStart.setEnabled(true);
					mnSynchronize.setEnabled(true);
					mntmTwoPhaseCommit.setEnabled(true);
				} catch (XmlException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} 
			}
		});
		
		mntmStart.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				try {			
					strHost = new String(xmlRoot.getTagValue("host"));
					strRegistry = new String(xmlRoot.getTagValue("registry"));
					String strNamingRebind = "rmi://" + strHost + "/" + strRegistry;
					
					accServer=null;
					accServer=new AccessDBImpl();
					Naming.rebind(strNamingRebind, accServer);
					writeFileLog("Server " + strHost + "-" + strRegistry + " is running\n");
					txtrServersLog.setText(readFileLog(fileLog));
					
					mntmStop.setEnabled(true);
					mntmStart.setEnabled(false);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		
		mntmStop.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				try {
					accServer.stopConnection();
					writeFileLog("Releasing connection\n");
					txtrServersLog.setText(readFileLog(fileLog));
					
					mntmStart.setEnabled(true);
					mntmStop.setEnabled(false);
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (RemoteException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		
		mntmExit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				writeFileLog("Closing server");
				try {
					txtrServersLog.setText(readFileLog(fileLog));
				} catch (FileNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				frmServermanager.dispose();
			}
		});
	}
	
	public void writeFileLog(String strCurrentLog) {
		try {
			BufferedWriter writer = new BufferedWriter(new FileWriter(fileLog, true));
			writer.write(strCurrentLog);
			writer.close();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}		
	}
	
	public String readFileLog(File fileLog) throws FileNotFoundException {
		String everything = new String();
	    BufferedReader br = new BufferedReader(new FileReader(fileLog));
	    try {
	        StringBuilder sb = new StringBuilder();
	        String line = br.readLine();

	        while (line != null) {
	            sb.append(line);
	            sb.append("\n");
	            line = br.readLine();
	        }
	        everything = sb.toString();
	    } catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
	        try {
				br.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	    }
	    
	    return everything;
	}

	public JTextArea getTxtrServersLog() {
		return txtrServersLog;
	}
	public JMenuBar getMenuBar() {
		return menuBar;
	}
	public JMenuItem getMntmLoadConfiguration() {
		return mntmLoadConfiguration;
	}
	public JMenu getMnMain() {
		return mnMain;
	}
	public JMenuItem getMntmStop() {
		return mntmStop;
	}
	public JMenuItem getMntmExit() {
		return mntmExit;
	}
	public JMenuItem getMntmStart() {
		return mntmStart;
	}
	public JMenuItem getMntmTwoPhaseCommit() {
		return mntmTwoPhaseCommit;
	}
	public JMenu getMnSynchronize() {
		return mnSynchronize;
	}
}
